# -*- coding: utf-8 *-*
from graphs.matrixgraph import *
from graphs.listgraph import *
from structures.hashtable import HashTable
from imdb.dbactors import DBActors

# Total
# Around 1450000 actors
# Around 819000 actresses
# RAM: 524.8 MB


class Main():

    def __init__(self):
        pass

    def main(self):
        filenames = ['C:/Juan/imdb/actors.list', 'C:/Juan/imdb/actresses.list']
        graphfilename = 'C:/Juan/imdb/imdb.graph.txt'
#        self.generate_graph(filenames, graphfilename)

        self.query_graph(graphfilename)

    def query_graph(self, graphfilename):
        print 'Loading graph', graphfilename, '...'

        graph = ListGraph(3000000)
        graph.load(graphfilename)

        input = None

        while input != 'quit':
            print '------------------------------------------------'
            input = raw_input("Enter action ['query' or 'quit']: ")
            print '------------------------------------------------'
            if input == 'query':
                actor = raw_input("Enter actors name: ")
                distance = raw_input("Enter minimum distance: ")
                d = int(distance)
                try:
                    print 'Processing, please wait...'
                    actors = graph.run_dijkstra(actor, d)
                    result = 'There are ' + str(actors.count()) + ' actors'
                    result += ' farther than ' + distance
                    result += ' from ' + actor
                    print result
                except Exception:
                    print 'Invalid actors.'

        print 'Thank you, come back soon!'

    def generate_graph(self, filenames, outputfilename):
        print 'Generating graph...'
        graph = ListGraph(3000000)
        movies = HashTable(3000000)

        for filename in filenames:
            print "Processing ", filename
            dbactors = DBActors(filename)
            dbactors.open()

            currentactor = None
            num = 0
            while not dbactors.finished():
                # Get actor and movie from line
                actor, title = dbactors.next()

                if actor is not None:
                    indexcurrentactor = graph.vertex_count()
                    graph.add_vertex(actor)

                    # Print counter and verify if maximum reached
                    num += 1
                    if num % 1000 == 0:
                        print num
                    if num > 1000 * 100:
                        break

                if title is not None:
                    movie = movies[title]

                    if movie is None:
                        movie = HashTable()
                        movies[title] = movie

                    if indexcurrentactor is not None:
                        movie[indexcurrentactor] = None
                    else:
                        raise Exception('Oh no! Current actor is null!')

            dbactors.close()

        for movie in movies.get_values():
            actors = movie.get_keys()
            for indexsrc in actors:
                for indexdest in actors:
                    if indexsrc != indexdest:
                        src = graph.get_vertex(indexsrc)
                        dest = graph.get_vertex(indexdest)
                        graph.add_edge(src, dest, 1)

        graph.save(outputfilename)

    def generate_list(self, filename):
        actors = open(filename + '.txt', 'w+')

        dbactors = DBActors(filename)
        dbactors.open()

        while not dbactors.finished():
            actor, title = dbactors.next()

            if actor is not None:
                actors.write('\n')
                actors.write(actor + ': ')
            if title is not None:
                actors.write(title + '; ')

        actors.close()

    def preview(self, filename, numlines=1000):
        file = open(filename)

        for i in range(numlines):
            print file.readline()

        file.close()


if __name__ == '__main__':
    main = Main()
    main.main()
